﻿
Namespace internalFunctions
    'parameters, functionName, any, convert to string, the original function name
    '            alias, any, convert to string, the alias
    '            mapping, optional, any, convert to string, new iParametersMapping
    '            serialmapping, optional, any, convert to string, new serial_parameters_mapping
    '            parameters, optional, any, convert to string, a parameters_list to overwrite the one in old function
    '            global, optional, boolean, whether the function should be set to shared context
    'return, bool, whether create alias success or not
    Public Class createalias
        Inherits internalFunction

        Public Class parameters
            Public Const functionName As String = "functionName"
            Public Const [alias] As String = "alias"
            Public Const parameters As String = "parameters"
            Public Const mapping As String = "mapping"
            Public Const serialmapping As String = "serialmapping"
            Public Const serialmapping1 As String = "serialmapping1"
            Public Const serialmapping2 As String = "serialmapping2"
            Public Const [global] As String = "global"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialMapping(m, parameters.functionName, parameters.alias, parameters.mapping, parameters.parameters)
        End Sub

        Public Sub New()
            MyBase.New("alias", m)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            Dim functionName As String = Nothing
            If ctx.findVariableStr(parameters.functionName, functionName) Then
                Dim [alias] As String = Nothing
                If ctx.findVariableStr(parameters.alias, [alias]) Then
                    Dim s As String = Nothing
                    Dim m As iParametersMapping = Nothing
                    If ctx.findVariableStr(parameters.mapping, s) AndAlso _
                       Not parameters_mapping(Of _maxInt64).parse(s, 0, m) Then
                        raiseError("cannot parse parameter " + parameters.mapping + ", " + s + ", ignore.", _
                                   errorHandle.errorType.user)
                        m = Nothing
                    End If
                    If m Is Nothing AndAlso _
                       ctx.findVariableStr(parameters.serialmapping, s) AndAlso _
                       Not parameters_mapping(Of _0).parse(s, 0, m) Then
                        raiseError("cannot parse parameter " + parameters.serialmapping + ", " + s + ", ignore.", _
                                   errorHandle.errorType.user)
                        m = Nothing
                    End If
                    If m Is Nothing AndAlso _
                       ctx.findVariableStr(parameters.serialmapping1, s) AndAlso _
                       Not parameters_mapping(Of _1).parse(s, 0, m) Then
                        raiseError("cannot parse parameter " + parameters.serialmapping1 + ", " + s + ", ignore.", _
                                    errorHandle.errorType.user)
                        m = Nothing
                    End If
                    If m Is Nothing AndAlso _
                       ctx.findVariableStr(parameters.serialmapping2, s) AndAlso _
                       Not parameters_mapping(Of _2).parse(s, 0, m) Then
                        raiseError("cannot parse parameter " + parameters.serialmapping2 + ", " + s + ", ignore.", _
                                    errorHandle.errorType.user)
                        m = Nothing
                    End If

                    Dim pl As parameters_list = Nothing
                    If ctx.findVariableStr(parameters.parameters, s) AndAlso _
                       Not parameters_list.parse(s, 0, pl) Then
                        raiseError("cannot parse parameter " + parameters.parameters + ", " + s + ", ignore.", _
                                   errorHandle.errorType.user)
                        pl = Nothing
                    End If

                    Dim rtn As Boolean = False
                    Dim func As [function] = Nothing
                    If ctx.findFunction(functionName, func) Then
                        'make a copy of the function, and remove all existing alias
                        Dim newfunc As [function] = Nothing
                        newfunc = func.clone(name:=[alias], mapping:=m, parameters:=pl, _
                                             copyName:=False, copyMapping:=(m Is Nothing), _
                                             copyParameters:=(pl Is Nothing), copyAliases:=False)
                        Dim destctx As context = Nothing
                        If ctx.findVariableBool(parameters.[global]) Then
                            destctx = sharedContext
                        Else
                            destctx = ctx.parent()
                        End If
                        rtn = (destctx.insertFunction(newfunc) <> destctx.functions_end())
                    Else
                        raiseError("cannot find function " + functionName, errorHandle.errorType.user)
                        rtn = False
                    End If
                    output = New bare_variable(typeDefination.bool, rtn)
                    Return True
                Else
                    raiseError("expect parameter " + parameters.alias, errorHandle.errorType.user)
                    Return False
                End If
            Else
                raiseError("expect parameter " + parameters.functionName, errorHandle.errorType.user)
                Return False
            End If
        End Function
    End Class
End Namespace